package com.ruoyi.factory.manpower.domain;

import java.lang.reflect.Type;
import java.util.*;
import com.google.gson.*;
import com.google.gson.reflect.TypeToken;

/**
 * 对象基类
 * Created by es on 2018/3/13.
 */
public abstract class BaseObject implements IModelToMap {

    public BaseObject() {
    }

    //region 对象的方法

    public JsonElement toJson() {
        return toJson(this);
    }

    @Override
    public String toString() {
        return toString(this);
    }

    /**
     * 将当前对象转换成另一个对象
     *
     * @param cls
     * @param <T>
     * @return
     */
    public <T> T toBean(Class<T> cls) {
        return toBean(this, cls);
    }

    /**
     * 将当前对象转换成map
     *
     * @return
     */
    @Override
    public Map<String, Object> toMap() {
        return toMap(this);
    }

    /**
     * 讲当前对象转换成StringMap
     *
     * @return
     */
    @Override
    public Map<String, String> toStringMap() {
        return toStringMap(this);
    }

    //endregion

    //region 静态方法

    //gson对象
    private static final Gson myGson = new GsonBuilder()
            //设置gson转换后的字符串为一个比较好看的字符串
//            .setPrettyPrinting()
            //设置默认Date解析时对应的format格式
            .setDateFormat("yyyyMMddHHmmss")
            //禁止转义html标签
            .disableHtmlEscaping()
            //启用复杂k-v映射序列化
            .enableComplexMapKeySerialization()
            .create();

    /**
     * 将实体对象转换成json字符串
     *
     * @param src
     * @return
     */
    public static String toString(Object src) {
        return myGson.toJson(src);
    }

    /**
     * 将实体对象转换成其他指定对象
     *
     * @param src 要转换的实体对象
     * @param cls 指定的其他对象类型
     * @param <T>
     * @return
     */
    public static <T> T toBean(Object src, Class<T> cls) {
        return myGson.fromJson(toString(src), cls);
    }

    /**
     * 将json字符串转换成指定对象
     *
     * @param json
     * @param cls
     * @param <T>
     * @return
     */
    public static <T> T toBean(String json, Class<T> cls) {
        return myGson.fromJson(json, cls);
    }

    /**
     * 将json字符串转换成指定对象
     *
     * @param json    json字符串
     * @param typeOfT 对象类型
     *                如果是泛型，可以使用TypeToken，如 new TypeToken<List<String>>() {}.getType()
     * @param <T>
     * @return
     */
    public static <T> T toBean(String json, Type typeOfT) {
        return myGson.fromJson(json, typeOfT);
    }

    /**
     * 将实体对象转换成json对象
     *
     * @param src
     * @return
     */
    public static JsonElement toJson(Object src) {
        if (src == null) {
            return null;
        }
        return myGson.toJsonTree(src);
    }

    /**
     * 将实体对象转换成map对象
     *
     * @param src
     * @return
     */
    public static Map<String, Object> toMap(Object src) {
        if (src == null) {
            return null;
        }
        JsonElement jsonElement = toJson(src);
        if (jsonElement instanceof JsonObject) {
            return toMap((JsonObject) jsonElement);
        } else {
            return new HashMap<String, Object>();
        }
    }

    /**
     * 将jsonObject对象转换成map
     *
     * @param jsonObject
     * @return
     */
    public static Map<String, Object> toMap(JsonObject jsonObject) {
        Map<String, Object> map = new HashMap<String, Object>();
        if (jsonObject == null) {
            return null;
        }
        Set<Map.Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
        JsonPrimitive primitive = null;
        for (Iterator<Map.Entry<String, JsonElement>> iter = entrySet.iterator(); iter.hasNext(); ) {
            Map.Entry<String, JsonElement> entry = iter.next();
            String key = entry.getKey();
            Object value = entry.getValue();
            if (value instanceof JsonArray) {
                map.put(key, toList((JsonArray) value));
            } else if (value instanceof JsonObject) {
                map.put(key, toMap((JsonObject) value));
            } else if (value instanceof JsonPrimitive) {
                primitive = (JsonPrimitive) value;
                if (primitive.isNumber()) {
                    map.put(key, primitive.getAsNumber());
                } else if (primitive.isString()) {
                    map.put(key, primitive.getAsString());
                } else if (primitive.isBoolean()) {
                    map.put(key, primitive.getAsBoolean());
                } else if (primitive.isJsonArray()) {
                    map.put(key, toList(primitive.getAsJsonArray()));
                } else if (primitive.isJsonObject()) {
                    map.put(key, toMap(primitive.getAsJsonObject()));
                } else if (primitive.isJsonNull()) {
                    map.put(key, null);
                } else if (primitive.isJsonPrimitive()) {
                    map.put(key, primitive.getAsString());
                } else {
                    map.put(key, value);
                }
            } else {
                map.put(key, value);
            }
        }
        return map;
    }

    /**
     * 将实体对象转换成StringMap
     *
     * @param src
     * @return
     */
    public static Map<String, String> toStringMap(Object src) {
        if (src == null) {
            return null;
        }
        JsonElement jsonElement = toJson(src);
        if (jsonElement instanceof JsonObject) {
            return toStringMap((JsonObject) jsonElement);
        } else {
            return new HashMap<String, String>();
        }
    }

    /**
     * 将jsonObject对象转换成StringMap
     *
     * @param jsonObject
     * @return
     */
    public static Map<String, String> toStringMap(JsonObject jsonObject) {
        Map<String, String> map = new HashMap<String, String>();
        if (jsonObject == null) {
            return null;
        }
        Set<Map.Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
        for (Iterator<Map.Entry<String, JsonElement>> iter = entrySet.iterator(); iter.hasNext(); ) {
            Map.Entry<String, JsonElement> entry = iter.next();
            String key = entry.getKey();
            JsonElement value = entry.getValue();
            if (value != null) {
                map.put(key, value.getAsString());
            }
        }
        return map;
    }

    /**
     * 将json字符串转化为list
     *
     * @param json
     * @return
     */
    public static <T> List<T> toList(String json) {
        return toList(json, new TypeToken<List<T>>() {
        }.getType());
    }

    /**
     * 将json字符串转化为list
     *
     * @param json
     * @param typeOfT
     * @return
     */
    public static <T> List<T> toList(String json, Type typeOfT) {
        List<T> list = myGson.fromJson(json, typeOfT);
        return list;
    }

    /**
     * JsonArray转list数组
     *
     * @param json
     * @return
     */
    public static List<Object> toList(JsonArray json) {
        List<Object> list = new ArrayList<Object>();
        for (int i = 0; i < json.size(); i++) {
            Object value = json.get(i);
            if (value instanceof JsonArray) {
                list.add(toList((JsonArray) value));
            } else if (value instanceof JsonObject) {
                list.add(toMap((JsonObject) value));
            } else {
                list.add(value);
            }
        }
        return list;
    }

    //endregion

}
